import type { IAppData, IParam, IHttpResponse } from '@/core';
import { setSessionStorage, getSessionStorage } from '@/core';
import { Http } from '@/http';
import { useAppStoreWithOut, useAuthResourceStoreWithOut } from '@/store';
import { AxiosResponse } from 'axios';
import { getCookie } from 'qx-util';

/**
 * 权限守卫
 *
 * @class AuthGuard
 */
class AuthGuard {
	/**
	 * 权限守卫实例对象
	 *
	 * @private
	 * @static
	 * @type {AuthGuard}
	 * @memberof AuthGuard
	 */
	private static authGuard: AuthGuard;

	/**
	 * Creates an instance of AuthGuard.
	 * 私有化构造器，只能通过getInstance()获取实例对象
	 * @memberof AuthGuard
	 */
	private constructor() {}

	/**
	 * 获取权限守卫实例对象
	 *
	 * @static
	 * @return {*}  {AuthGuard}
	 * @memberof AuthGuard
	 */
	static getInstance(): AuthGuard {
		if (!this.authGuard) {
			this.authGuard = new AuthGuard();
		}
		return this.authGuard;
	}

	/**
	 * 权限守卫入口方法
	 *
	 * @param {string} url 请求路径
	 * @param {IParam} [params={}] 额外参数
	 * @return {Promise<boolean>}
	 * @memberof AuthGuard
	 */
	public authGuard(url: string, params: IParam = {}): Promise<boolean> {
		if (import.meta.env.VITE_MODE === 'R7') {
			return this.getAppliDataWithOld(url, params);
		} else {
			return this.getAppliDataWithNew(url, params);
		}
	}

	/**
	 * 老模式
	 *
	 * @private
	 * @param {string} url
	 * @param {IParam} [params={}]
	 * @return {*}  {Promise<any>}
	 * @memberof AuthGuard
	 */
	private getAppliDataWithOld(url: string, params: IParam = {}): Promise<any> {
		return new Promise((resolve: Function, reject: Function) => {
			this.getAppData(url, params).then((result: any) => {
				result ? resolve(true) : reject(false);
			});
		});
	}

	/**
	 * 新模式
	 *
	 * @private
	 * @param {string} url
	 * @param {IParam} [params={}]
	 * @return {*}  {Promise<any>}
	 * @memberof AuthGuard
	 */
	private getAppliDataWithNew(url: string, params: IParam = {}): Promise<any> {
		return new Promise((resolve: Function, reject: Function) => {
			const Environment = App.getEnvironment();
			if (Environment && Environment.SaaSMode) {
				if (getSessionStorage('avtiveOrgData')) {
					this.getAppData(url, params).then((result: any) => {
						result ? resolve(true) : reject(false);
					});
				} else {
					this.getOrgsByDcsystem().then((result: boolean) => {
						if (!result) {
							reject(false);
						} else {
							this.getAppData(url, params).then((result: any) => {
								result ? resolve(true) : reject(false);
							});
						}
					});
				}
			} else {
				this.getAppData(url, params).then((result: any) => {
					result ? resolve(true) : reject(false);
				});
			}
		});
	}

	/**
	 * 获取AppData
	 * @param url 路由
	 * @param params 参数
	 * @returns Promise<boolean>
	 */
	private getAppData(url: string, params: IParam = {}): Promise<boolean> {
		return new Promise((resolve: Function, reject: Function) => {
			const Environment = App.getEnvironment();
			if (Environment.EnableAppData) {
				const get: Promise<IHttpResponse> = Http.getInstance().get(url);
				get
					.then((response: IHttpResponse) => {
						if (response.success) {
							let { data } = response;
							if (data) {
								if (getCookie('ibzuaa-user')) {
									const user: IParam = JSON.parse(
										getCookie('ibzuaa-user') as string
									);
									let localAppData: IParam = {};
									if (user.sessionParams) {
										localAppData = { context: user.sessionParams };
										Object.assign(localAppData, data);
									}
									data = JSON.parse(JSON.stringify(localAppData));
								}
								if (localStorage.getItem('localData')) {
									const { addLocalData } = useAppStoreWithOut();
									addLocalData(
										JSON.parse(localStorage.getItem('localData') as string)
									);
								}
								const { addAppData } = useAppStoreWithOut();
								addAppData(data);
								const { commitAuthData } = useAuthResourceStoreWithOut();
								commitAuthData(data as IAppData);
							}
						}
						resolve(true);
					})
					.catch((error) => {
						App.login();
					});
			} else {
				console.warn('不启用AppData模式暂未支持');
			}
		});
	}

	/**
	 * 通过租户获取组织数据
	 *
	 * @memberof AuthGuard
	 */
	private getOrgsByDcsystem(): Promise<boolean> {
		return new Promise((resolve: Function) => {
			const Environment = App.getEnvironment();
			const tempViewParam = { srfdcsystem: Environment.SrfDcsystem };
			if (tempViewParam.srfdcsystem) {
				setSessionStorage('dcsystem', tempViewParam);
				const requestUrl = `/uaa/getbydcsystem/${tempViewParam.srfdcsystem}`;
				const get: Promise<IHttpResponse> = Http.getInstance().get(requestUrl);
				get
					.then((response: IHttpResponse) => {
						if (response.success) {
							const { data } = response;
							if (data && data.length > 0) {
								setSessionStorage('orgsData', data);
								setSessionStorage('activeOrgData', data[0]);
							}
							resolve(true);
						} else {
							resolve(false);
						}
					})
					.catch((error) => {
						App.login();
					});
			} else {
				console.warn('登录失败', '登录失败，请联系管理员');
				App.login();
			}
		});
	}
}
export default AuthGuard;
